#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/input.h>

char *photo_name[] = {"1.bmp", "2.bmp", "3.bmp", "4.bmp"};
struct input_event touch;

void BMPInsert(int bmp_fd, int *lcd_p)
{
    // 4.读图片文件54字节
    char buffer_1[54] = {0};
    int n = read(bmp_fd, buffer_1, sizeof(buffer_1));
    if (n == 0)
    {
        perror("read bmp error");
    }

    lseek(bmp_fd, 54, SEEK_SET);

    // 5.读图片文件800*480*3字节
    char RGBbf[800 * 480 * 3] = {0};
    n = read(bmp_fd, RGBbf, sizeof(RGBbf));

    // 6.将读取出来的RGB数据转化成ARGB数据
    int ARGBbf[800 * 480] = {0};
    for (int i = 0; i < 800 * 480; i++)
    {
        ARGBbf[i] = RGBbf[3 * i] << 0 | RGBbf[3 * i + 1] << 8 | RGBbf[3 * i + 2] << 16 | 0x00 << 24;
    }

    // 7.将数据颠倒和写入
    for (int y = 0; y < 480; y++)
    {
        for (int x = 0; x < 800; x++)
        {
            *(lcd_p + x + y * 800) = ARGBbf[x + (479 - y) * 800];
        }
    }

    // 8.关闭图片文件
    close(bmp_fd);
}

int openbmp(char *name)
{
    // 2.打开图片文件
    int bmp_fd = open(name, O_RDWR);
    if (bmp_fd == -1)
    {
        perror("open lcd error");
        return -1;
    }
    return bmp_fd;
}

void movephoto(int *lcd_p)
{
    int count = 0;
    while (count < 4)
    {
        int bmp_fd = openbmp(photo_name[count]);
        BMPInsert(bmp_fd, lcd_p);
        sleep(2);
        count++;
    }
}

void Touch(int ts_fd, int *x, int *y)
{
    read(ts_fd, &touch, sizeof(touch)); // 没触摸的时候。read是堵塞的
    if (touch.type == EV_ABS && touch.code == ABS_X)
        *x = touch.value * 800 / 1024; // 判断是不是触摸屏设备，在判断是不是x坐标，
    if (touch.type == EV_ABS && touch.code == ABS_Y)
        *y = touch.value * 480 / 600;
    if (touch.type == EV_KEY && touch.code == BTN_TOUCH && touch.value == 0) // 判断是否手离开
    {
        printf("x:%d--y:%d\n", (*x) * 800 / 1024, (*y) * 480 / 600); // 黑板
    }
}

int main()
{
    // 显示图片的步骤

    // 1.打开LCD文件
    int lcd_fd = open("/dev/fb0", O_RDWR);
    if (lcd_fd == -1)
    {
        perror("open lcd error");
    }

    // 打开触摸屏
    int ts_fd = open("/dev/input/event0", O_RDONLY);
    if (ts_fd == -1)
    {
        printf("打开触摸屏失败！\n");
        return -1;
    }

    // 3.内存映射
    int *lcd_p = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd, 0);
    if (lcd_p == NULL)
        perror("mmap error");

    // 要求模块
    // int in = -1;
    // while (1)
    // {
    //     printf("请输入要显示的图片编号(输入0退出程序)：");
    //     scanf("%d", &in);
    //     int bmp_fd = 0;
    //     switch (in)
    //     {
    //     case 1:
    //         // 打开bmp
    //         bmp_fd = openbmp(photo_name[in]);
    //         BMPInsert(bmp_fd, lcd_p);
    //         break;
    //     case 2:
    //         bmp_fd = openbmp(photo_name[in]);
    //         BMPInsert(bmp_fd, lcd_p);
    //         break;
    //     case 3:
    //         bmp_fd = openbmp(photo_name[in]);
    //         BMPInsert(bmp_fd, lcd_p);
    //         break;
    //     case 4:
    //         bmp_fd = openbmp(photo_name[in]);
    //         BMPInsert(bmp_fd, lcd_p);
    //         break;
    //     case 5:
    //         movephoto(lcd_p);
    //         break;
    //     case 0:
    //         // 9.解除内存映射
    //         munmap(lcd_p, 800 * 480 * 4);
    //         // 10.关闭LCD文件
    //         close(lcd_fd);
    //         exit(0);
    //         break;
    //     default:
    //         break;
    //     }
    // }
    int count = 0;
    int bmp_fd = 0;
    int x, y = 0;
    while (1)
    {
        // Touch(ts_fd,&x, &y);

        read(ts_fd, &touch, sizeof(touch)); // 没触摸的时候。read是堵塞的
        if (touch.type == EV_ABS && touch.code == ABS_X)
            *x = touch.value * 800 / 1024; // 判断是不是触摸屏设备，在判断是不是x坐标，
        if (touch.type == EV_ABS && touch.code == ABS_Y)
            *y = touch.value * 480 / 600;
        if (touch.type == EV_KEY && touch.code == BTN_TOUCH && touch.value == 0) // 判断是否手离开
        {
            printf("x:%d--y:%d\n", (*x) * 800 / 1024, (*y) * 480 / 600); // 黑板
            if (x >= 0 && x <= 400)                                      // 左半部分
            {
                count++;
                if (count > 3)
                    count = 0;
                bmp_fd = openbmp(photo_name[count]);
                BMPInsert(bmp_fd, lcd_p);
            }
            else if (x >= 400 && x < 800) // 右半部分
            {
                if ((y >= 0 && y <= 50) && (x >= 750 && x < 800))
                {
                    movephoto(lcd_p);
                }
                else
                {
                    count--;
                    if (count < 0)
                        count = 3;
                    bmp_fd = openbmp(photo_name[count]);
                    BMPInsert(bmp_fd, lcd_p);
                }
            }
        }
    }

    // 9.解除内存映射
    munmap(lcd_p, 800 * 480 * 4);
    // 10.关闭LCD文件
    close(lcd_fd);
    close(ts_fd);
    return 0;
}